package com.hotel.management.service;

import com.hotel.management.dto.EmployeeDTO;
import com.hotel.management.dto.EmployeeQueryDTO;
import com.hotel.management.dto.PageResult;
import com.hotel.management.entity.Employee;

import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * 员工服务接口
 * 定义员工管理相关的业务操作
 * 
 * @author Hotel Management Team
 * @version 1.0.0
 * @since 2024-06-28
 */
public interface EmployeeService {

    /**
     * 创建员工
     * 
     * @param employeeDTO 员工数据传输对象
     * @return 创建的员工信息
     * @throws com.hotel.management.exception.DuplicateEmployeeException 当员工信息重复时
     */
    EmployeeDTO createEmployee(@Valid @NotNull EmployeeDTO employeeDTO);

    /**
     * 根据ID查询员工信息
     * 
     * @param id 员工ID
     * @return 员工信息，如果不存在则抛出异常
     * @throws com.hotel.management.exception.EmployeeNotFoundException 当员工不存在时
     */
    EmployeeDTO getEmployeeById(@NotNull Long id);

    /**
     * 查询所有员工信息
     * 
     * @return 员工列表
     */
    List<EmployeeDTO> getAllEmployees();

    /**
     * 更新员工信息
     * 
     * @param id 员工ID
     * @param employeeDTO 员工数据传输对象
     * @return 更新后的员工信息
     * @throws com.hotel.management.exception.EmployeeNotFoundException 当员工不存在时
     * @throws com.hotel.management.exception.DuplicateEmployeeException 当员工信息重复时
     */
    EmployeeDTO updateEmployee(@NotNull Long id, @Valid @NotNull EmployeeDTO employeeDTO);

    /**
     * 删除员工信息
     * 
     * @param id 员工ID
     * @throws com.hotel.management.exception.EmployeeNotFoundException 当员工不存在时
     */
    void deleteEmployee(@NotNull Long id);

    /**
     * 根据姓名查询员工信息（模糊查询）
     * 
     * @param name 员工姓名
     * @return 员工列表
     */
    List<EmployeeDTO> getEmployeesByName(@NotNull String name);

    /**
     * 根据职位查询员工信息
     * 
     * @param position 职位名称
     * @return 员工列表
     */
    List<EmployeeDTO> getEmployeesByPosition(@NotNull String position);

    /**
     * 根据状态查询员工信息
     * 
     * @param status 员工状态
     * @return 员工列表
     */
    List<EmployeeDTO> getEmployeesByStatus(@NotNull String status);

    /**
     * 根据角色ID查询员工信息
     * 
     * @param roleId 角色ID
     * @return 员工列表
     */
    List<EmployeeDTO> getEmployeesByRoleId(@NotNull Long roleId);

    /**
     * 分页查询员工信息
     * 
     * @param queryDTO 查询条件
     * @return 分页结果
     */
    PageResult<EmployeeDTO> getEmployeesWithPage(@Valid @NotNull EmployeeQueryDTO queryDTO);

    /**
     * 批量创建员工
     * 
     * @param employeeDTOs 员工数据传输对象列表
     * @return 创建成功的员工数量
     * @throws com.hotel.management.exception.DuplicateEmployeeException 当员工信息重复时
     */
    int batchCreateEmployees(@NotEmpty List<@Valid EmployeeDTO> employeeDTOs);

    /**
     * 批量删除员工
     * 
     * @param ids 员工ID列表
     * @return 删除成功的员工数量
     */
    int batchDeleteEmployees(@NotEmpty List<Long> ids);

    /**
     * 更新员工状态
     * 
     * @param id 员工ID
     * @param status 新状态
     * @throws com.hotel.management.exception.EmployeeNotFoundException 当员工不存在时
     */
    void updateEmployeeStatus(@NotNull Long id, @NotNull String status);

    /**
     * 检查员工是否存在
     * 
     * @param id 员工ID
     * @return 如果存在返回true，否则返回false
     */
    boolean existsById(@NotNull Long id);

    /**
     * 根据手机号查询员工信息
     * 
     * @param phone 手机号
     * @return 员工信息，如果不存在则返回null
     */
    EmployeeDTO getEmployeeByPhone(@NotNull String phone);

    /**
     * 根据邮箱查询员工信息
     * 
     * @param email 邮箱地址
     * @return 员工信息，如果不存在则返回null
     */
    EmployeeDTO getEmployeeByEmail(@NotNull String email);

    /**
     * 统计员工总数
     * 
     * @return 员工总数
     */
    long countAllEmployees();

    /**
     * 根据条件统计员工数量
     * 
     * @param queryDTO 查询条件
     * @return 符合条件的员工数量
     */
    long countEmployeesByCondition(@Valid @NotNull EmployeeQueryDTO queryDTO);

    /**
     * 将Employee实体转换为EmployeeDTO
     * 
     * @param employee 员工实体
     * @return 员工数据传输对象
     */
    EmployeeDTO convertToDTO(Employee employee);

    /**
     * 将EmployeeDTO转换为Employee实体
     * 
     * @param employeeDTO 员工数据传输对象
     * @return 员工实体
     */
    Employee convertToEntity(EmployeeDTO employeeDTO);
}
